package com.bxl.netty.rpc.server.filter;





import com.bxl.netty.rpc.common.filter.Filter;
import com.bxl.netty.rpc.common.message.MsgResponseContent;
import com.bxl.netty.rpc.common.message.PackageMsg;
import com.bxl.netty.rpc.common.message.RpcContent;
import com.bxl.netty.rpc.server.register.BeanRegister;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * <>
 *
 * @author baixl
 * @date 2021/2/25
 */
public class FilterChain implements Filter {
    private List<Filter> filters = new ArrayList<Filter>();

    public void registerFilter(Filter filter) {
        this.filters.add(filter);
    }

    public void doFilter(PackageMsg msg, MsgResponseContent content, Filter filter) {
        InnerFilterChain chain = new InnerFilterChain(filters);
        chain.doFilter(msg, content, this);
    }

    private static class InnerFilterChain implements Filter {
        private List<Filter> filters = new ArrayList<Filter>();
        private int index = 0;

        public InnerFilterChain(List<Filter> filters) {
            this.filters = filters;
        }

        public void doFilter(PackageMsg msg, MsgResponseContent content, Filter filter) {
            if (index < filters.size()) {
                index++;
                filters.get(index - 1).doFilter(msg, content, this);
            } else {
                try {
                    content.setContent(invoke((RpcContent)msg.getContent()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        private Object invoke(RpcContent content) throws Exception {
            System.out.println("invoke " +content.getName());
            Object bean = BeanRegister.getBean(content.getName());
            //可以修改为将常用的method缓存起来，不要每次通过反射取方法
            Method method = bean.getClass().getMethod(content.getMethodName(), content.getParameterTypes());
            return method.invoke(bean, content.getArgs());
        }
    }
}
